﻿using Microsoft.AspNetCore.Localization;
using RuoVea.ExConfig;
using System.Globalization;

namespace RuoVea.OmiDict.Extensions;

/// <summary>
/// 
/// </summary>
public static class LocalizationExtensions
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="app"></param>
    /// <returns></returns>
    public static IApplicationBuilder UseOmiLocalization(this IApplicationBuilder app)
    {
        var supportedCultures = AppSettings.GetAppSettings<List<string>>("Lang:Cultures").Select(x => new CultureInfo(x)).ToList();

        var options = new RequestLocalizationOptions
        {
            DefaultRequestCulture = new RequestCulture(AppSettings.app("Lang", "Default")), // 默认文化
            SupportedCultures = supportedCultures,
            SupportedUICultures = supportedCultures
        };
        // 配置使用 "lang" 参数的文化提供程序
        options.RequestCultureProviders = new List<IRequestCultureProvider>
            {
                // 自定义Cookie提供程序，读取简写的"lang" Cookie并映射到完整文化代码
                new ShortLangCookieRequestCultureProvider(),
                // 默认的Cookie提供程序
                new CookieRequestCultureProvider(),
                new AcceptLanguageHeaderRequestCultureProvider()
            };

        app.UseRequestLocalization(options);
        app.Use(async (context, next) =>
        {
            // 检查查询参数中是否有lang参数
            var lang = context.Request.Query["lang"].FirstOrDefault();
            if (!string.IsNullOrEmpty(lang))
            {
                var expires = DateTimeOffset.Now.AddDays(30).ToString("R");
                // 如果是简写格式，也设置简写格式的Cookie（保持前端一致性）
                var cookieValue = $"webapp:lang={lang}; expires={expires}; path=/; samesite=lax";
                context.Response.Headers.Append("Set-Cookie", cookieValue);
            }
            await next();
        });

        return app;
    }
}

/// <summary>
/// 
/// </summary>
public static class ShortLanguageMapper
{
    /// <summary>
    /// 
    /// </summary>
    public static Dictionary<string, string> languageMap = AppSettings.GetAppSettings<Dictionary<string, string>>("Lang:Map");
    /// <summary>
    /// 
    /// </summary>
    /// <param name="shortCode"></param>
    /// <returns></returns>
    public static string MapToFullCultureCode(string shortCode)
    {
        if (string.IsNullOrWhiteSpace(shortCode))
            return null;

        // 如果已经是完整格式，直接返回
        if (shortCode.Contains('-'))
            return shortCode;

        // 查找映射
        if (languageMap.TryGetValue(shortCode.ToLower(), out var fullCode))
            return fullCode;

        // 如果没有找到映射，尝试创建CultureInfo来验证
        try
        {
            var culture = new CultureInfo(shortCode);
            return culture.Name;
        }
        catch
        {
            return null;
        }
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="shortCode"></param>
    /// <returns></returns>
    public static bool IsValidShortCode(string shortCode)
    {
        return !string.IsNullOrWhiteSpace(shortCode) && (languageMap.ContainsKey(shortCode.ToLower()) || shortCode.Contains('-'));
    }
}


/// <summary>
/// 自定义Cookie请求文化提供程序（支持简写lang）
/// </summary>
public class ShortLangCookieRequestCultureProvider : RequestCultureProvider
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="httpContext"></param>
    /// <returns></returns>
    /// <exception cref="ArgumentNullException"></exception>
    public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
    {
        if (httpContext == null)
        {
            throw new ArgumentNullException(nameof(httpContext));
        }

        var cookie =  httpContext.Request.Cookies["webapp:lang"] ??httpContext.Request.Cookies["lang"];
        if (string.IsNullOrEmpty(cookie))
        {
            return NullProviderCultureResult;
        }

        // 映射简写代码到完整文化代码
        var fullCultureCode = ShortLanguageMapper.MapToFullCultureCode(cookie);
        if (fullCultureCode != null)
        {
            return Task.FromResult(new ProviderCultureResult(fullCultureCode, fullCultureCode));
        }

        return NullProviderCultureResult;
    }
}

/// <summary>
/// 
/// </summary>
public class LangConfig
{
    /// <summary>
    /// 
    /// </summary>
    public string Default { get; set; }
    /// <summary>
    /// 
    /// </summary>
    public string Cultures { get; set; }
    /// <summary>
    /// 
    /// </summary>
    public Dictionary<string, string> Map { get; set; }
}
